package com.cloud.report.common.dynamic;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import com.cloud.report.api.entity.ReportDatasource;

@Aspect
@Component
@Order(-1)
public class DynamicDataSourceAspect implements ApplicationContextAware {
	private ApplicationContext applicationContext;

	@Pointcut("@annotation(com.cloud.report.common.dynamic.DynamicDataSource)")
	public void dynamicDataSourcePointCut() {
	}

	@Before("dynamicDataSourcePointCut()")
	public void before(JoinPoint joinPoint) {
		String projectId = DataSourceUtils.DEFAULT;
		Object[] args = joinPoint.getArgs();
		if (args.length >= 1) {
			projectId = String.valueOf(args[0]);
		}
		projectId = StringUtils.defaultIfBlank(projectId, DataSourceUtils.DEFAULT);
		if (!DataSourceUtils.contains(projectId)) {
			DynamicRoutingDataSource dynamicDataSource = applicationContext.getBean(DynamicRoutingDataSource.class);
			JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);
			List<ReportDatasource> reportDataSources = jdbcTemplate.query(
					"select * from report_datasource where ds_name = ?",
					new BeanPropertyRowMapper<ReportDatasource>(ReportDatasource.class), projectId);
			if (null != reportDataSources && reportDataSources.size() == 1) {
				ReportDatasource reportDataSource = reportDataSources.get(0);
				dynamicDataSource.createDatasource(projectId, reportDataSource.getUrl(), reportDataSource.getUsername(),
						reportDataSource.getPassword(), reportDataSource.getDrivername());
				DynamicDataSourceHolder.set(DataSourceUtils.getDataSourceId(projectId));
				return;
			}
		}
		DynamicDataSourceHolder.set(DataSourceUtils.getDataSourceId(projectId));
	}

	@After("dynamicDataSourcePointCut()")
	public void after(JoinPoint joinPoint) {
		DynamicDataSourceHolder.clear();
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

}
